package org.jsola.contract.service.impl;

import org.jsola.contract.common.ExampleKit;
import org.jsola.contract.constant.AccountType;
import org.jsola.contract.constant.ContractConstants;
import org.jsola.contract.dao.IAccountDAO;
import org.jsola.contract.dto.AccountAddDTO;
import org.jsola.contract.dto.AccountUpdateDTO;
import org.jsola.contract.entity.AccountDO;
import org.jsola.contract.exception.ContractException;
import org.jsola.contract.query.AccountQuery;
import org.jsola.contract.service.IAccountService;
import org.jsola.contract.vo.AccountListVO;
import org.jsola.contract.vo.AccountVO;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static org.jsola.user.constant.UserConstants.DEFAULT_SITE_ID;

/**
 * 账户信息
 *
 * @author JanusMix
 */
@Service("contractAccountServiceImpl")
public class AccountServiceImpl implements IAccountService {

    @Autowired
    private IAccountDAO accountDAO;
    @Autowired
    private ThirdSignServiceImpl thirdSignService;

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public AccountVO save(AccountAddDTO accountAddDTO, TokenUser tokenUser) {
        AccountDO accountDO;
        //调用第三方注册
        if (AccountType.PERSON.getValue().equals(accountAddDTO.getType())) {
            accountDO = thirdSignService.addPersonAccount(accountAddDTO.getMemberId(),
                    accountAddDTO.getName(), accountAddDTO.getMobile(), accountAddDTO.getIdNo(), accountAddDTO.getPersonArea(), tokenUser);
        } else {
            throw new ContractException("暂不支持企业账户创建");
        }
        return accountDO.to(AccountVO.class);
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public int update(AccountUpdateDTO accountUpdateDTO, TokenUser tokenUser) {
        //转DO
        AccountDO accountDO = accountUpdateDTO.to(AccountDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(accountDO, DEFAULT_SITE_ID, tokenUser.getUserId());
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... accountIds) {
        return deleteByIds(DEFAULT_SITE_ID, tokenUser.getUserId(), (Object[]) accountIds);
    }


    @Override
    public AccountVO selectById(String accountId) {
        AccountDO accountDO = selectDOById(accountId);
        if (accountDO == null) {
            return null;
        }
        return accountDO.to(AccountVO.class);
    }

    @Override
    public List<AccountVO> selectByIds(List<String> accountIds) {
        Example example = new Example(AccountDO.class);
        example.and().andIn("id", accountIds);
        List<AccountDO> accountDOS = accountDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(accountDOS)) {
            return accountDOS == null ? null : new ArrayList<>();
        }
        return accountDOS.stream()
                .map(accountDO -> accountDO.to(AccountVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<AccountListVO> select(AccountQuery accountQuery) {
        List<AccountDO> accountDOList = selectDO(accountQuery);
        if (CollectionUtils.isEmpty(accountDOList)) {
            return accountDOList == null ? null : new ArrayList<>();
        }
        return accountDOList.stream()
                .map(accountDO -> accountDO.to(AccountListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(AccountQuery accountQuery) {
        Example example = buildExample(accountQuery);
        return accountDAO.selectCountByExample(example);
    }

    @Override
    public Page<AccountListVO> selectPage(AccountQuery accountQuery) {
        Example example = buildExample(accountQuery);
        Page<AccountDO> page = accountDAO.selectPageByExample(example,
                accountQuery.getPageNo(),
                accountQuery.getPageSize());

        return page.to(AccountListVO.class);
    }

    @Override
    public AccountDO selectDOById(String accountId) {
        return listById(accountId, DEFAULT_SITE_ID);
    }

    @Override
    public List<AccountDO> selectDO(AccountQuery accountQuery) {
        Example example = buildExample(accountQuery);
        return accountDAO.selectByExample(example);
    }

    @Override
    public AccountDO findAccount(AccountType type, String memberId) {
        ParamException.notNull(type, "type不能为空");
        ParamException.notNull(memberId, "成员id不能为空");
        Example example = new Example(AccountDO.class);
        example.and()
                .andEqualTo("type", type.getValue())
                .andEqualTo("memberId", memberId);
        return accountDAO.selectOneByExample(example);
    }

    @Override
    public List<AccountDO> findAccounts(AccountType type, List<String> memberIds) {
        if (CollectionUtils.isEmpty(memberIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(AccountDO.class);
        example.and()
                .andIn("memberId", memberIds)
                .andEqualTo("type", type.getValue())
                .andEqualTo("siteId", DEFAULT_SITE_ID);
        return accountDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public void updateUserPhone(String oldPhone, String memberId, String newPhone, TokenUser tokenUser) {
        ParamException.notNull(oldPhone, "旧手机号不能为空");
        ParamException.notNull(memberId, "成员id不能为空");
        ParamException.notNull(newPhone, "新手机号不能为空");

        Example example = new Example(AccountDO.class);
        example.and()
                .andEqualTo("mobile", oldPhone)
                .andEqualTo("memberId", memberId)
                .andEqualTo("type", AccountType.PERSON.getValue());

        AccountDO accountUp = new AccountDO();
        accountUp.setMobile(newPhone);
        accountUp.preUpdate(tokenUser.getUserId());
        // 根据条件更新
        accountDAO.updateByExampleSelective(accountUp, example);
    }

    @Override
    public AccountDO selectByAccountId(String accountId) {
        Example example = new Example(AccountDO.class);
        example.and()
                .andEqualTo("accountId", accountId)
                .andEqualTo("type", AccountType.PERSON.getValue())
                .andEqualTo("siteId", DEFAULT_SITE_ID);

        return accountDAO.selectOneByExample(example);
    }

    @Override
    public List<AccountDO> selectByAccountIds(List<String> accountIds) {
        if (CollectionUtils.isEmpty(accountIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(AccountDO.class);
        example.and()
                .andIn("accountId", accountIds)
                .andEqualTo("type", AccountType.PERSON.getValue())
                .andEqualTo("siteId", DEFAULT_SITE_ID);

        return accountDAO.selectByExample(example);
    }

    /**
     * 根据查询参数，构建example
     *
     * @param accountQuery 查询参数
     * @return example
     */
    private Example buildExample(AccountQuery accountQuery) {
        Example example = new Example(AccountDO.class);
        example.and()
                .andEqualTo("siteId", DEFAULT_SITE_ID);
        if (accountQuery.getAccountId() != null) {
            example.and().andEqualTo("accountId", accountQuery.getAccountId());
        }
        if (accountQuery.getType() != null) {
            example.and().andEqualTo("type", accountQuery.getType());
        }
        if (accountQuery.getMemberId() != null) {
            example.and().andEqualTo("memberId", accountQuery.getMemberId());
        }
        if (accountQuery.getSource() != null) {
            example.and().andEqualTo("source", accountQuery.getSource());
        }
        if (accountQuery.getPersonArea() != null) {
            example.and().andEqualTo("personArea", accountQuery.getPersonArea());
        }
        if (accountQuery.getIdNo() != null) {
            example.and().andEqualTo("idNo", accountQuery.getIdNo());
        }
        if (accountQuery.getName() != null) {
            example.and().andEqualTo("name", accountQuery.getName());
        }
        if (accountQuery.getMobile() != null) {
            example.and().andEqualTo("mobile", accountQuery.getMobile());
        }
        if (accountQuery.getEmail() != null) {
            example.and().andEqualTo("email", accountQuery.getEmail());
        }
        if (accountQuery.getOrgan() != null) {
            example.and().andEqualTo("organ", accountQuery.getOrgan());
        }
        if (accountQuery.getTitle() != null) {
            example.and().andEqualTo("title", accountQuery.getTitle());
        }
        if (accountQuery.getAddress() != null) {
            example.and().andEqualTo("address", accountQuery.getAddress());
        }
        if (accountQuery.getCountry() != null) {
            example.and().andEqualTo("country", accountQuery.getCountry());
        }
        if (accountQuery.getProvince() != null) {
            example.and().andEqualTo("province", accountQuery.getProvince());
        }
        if (accountQuery.getDepartment() != null) {
            example.and().andEqualTo("department", accountQuery.getDepartment());
        }
        if (accountQuery.getOrganType() != null) {
            example.and().andEqualTo("organType", accountQuery.getOrganType());
        }
        if (accountQuery.getUserType() != null) {
            example.and().andEqualTo("userType", accountQuery.getUserType());
        }
        if (accountQuery.getOrganCode() != null) {
            example.and().andEqualTo("organCode", accountQuery.getOrganCode());
        }
        if (accountQuery.getLegalName() != null) {
            example.and().andEqualTo("legalName", accountQuery.getLegalName());
        }
        if (accountQuery.getLegalArea() != null) {
            example.and().andEqualTo("legalArea", accountQuery.getLegalArea());
        }
        if (accountQuery.getAgentName() != null) {
            example.and().andEqualTo("agentName", accountQuery.getAgentName());
        }
        if (accountQuery.getAgentIdNo() != null) {
            example.and().andEqualTo("agentIdNo", accountQuery.getAgentIdNo());
        }
        if (accountQuery.getScope() != null) {
            example.and().andEqualTo("scope", accountQuery.getScope());
        }
        if (accountQuery.getRegType() != null) {
            example.and().andEqualTo("regType", accountQuery.getRegType());
        }
        if (accountQuery.getReal() != null) {
            example.and().andEqualTo("real", accountQuery.getReal());
        }
        // 排序
        ExampleKit.setExampleOrder(example, accountQuery.getOrders());
        return example;
    }
}




